import pandas as pd
import numpy as np
import openpyxl

# 手动实现MinMax归一化函数
def min_max_normalize(data):
    """将数据归一化到[0, 1]区间"""
    min_val = min(data)
    max_val = max(data)
    
    # 处理最大值和最小值相等的情况
    if max_val == min_val:
        return [0.5 for _ in data]
    
    return [(x - min_val) / (max_val - min_val) for x in data]

print('开始处理新浪财经历史分红数据...')

# 1. 读取文件"新浪财经历史分红数据.csv"，输出数据形状，并对变量"代码""名称""详细"的取值进行重复检查
try:
    # 读取CSV文件
    df = pd.read_csv('新浪财经历史分红数据.csv', encoding='utf-8-sig')
    print(f'成功读取数据，数据形状: {df.shape}')
    
    # 显示数据信息
    print('\n数据基本信息:')
    print(df.info())
    
    # 检查重复值
    print('\n各字段重复值检查:')
    # 使用实际数据中的列名
    code_duplicates = df['代码'].duplicated().sum()
    name_duplicates = df['名称'].duplicated().sum()
    detail_duplicates = df['详细'].duplicated().sum()
    
    print(f'代码字段重复值数量: {code_duplicates}')
    print(f'名称字段重复值数量: {name_duplicates}')
    print(f'详细字段重复值数量: {detail_duplicates}')
    
    # 2. 展示数据的前5行，观察数据存在的问题，并进行调整
    print('\n数据前5行:')
    print(df.head())
    
    # 检查数据是否有缺失值
    print('\n数据缺失值检查:')
    print(df.isnull().sum())
    
    # 3. 对"上市日期"进行处理，提取年、月、日变量
    print('\n处理上市日期字段...')
    df['上市日期'] = pd.to_datetime(df['上市日期'], format='%Y-%m-%d', errors='coerce')
    df['上市年份'] = df['上市日期'].dt.year
    df['上市月份'] = df['上市日期'].dt.month
    df['上市日'] = df['上市日期'].dt.day
    
    print('日期处理后的前5行数据:')
    print(df[['代码', '名称', '上市日期', '上市年份', '上市月份', '上市日']].head())
    
    # 4. 对数值型变量进行数据归一化处理
    print('\n对数值型变量进行归一化处理...')
    
    # 提取需要归一化的数值型变量（使用实际数据中的列名）
    numeric_cols = ['累计股息(%)', '年均股息(%)', '分红次数', '融资总额(亿)']
    
    # 处理可能的非数值型数据
    for col in numeric_cols:
        df[col] = pd.to_numeric(df[col], errors='coerce')
    
    # 填充缺失值
    df[numeric_cols] = df[numeric_cols].fillna(0)
    
    # 复制原始数据
    df_normalized = df.copy()
    
    # 使用手动归一化方法对每列进行处理
    for col in numeric_cols:
        # 获取列数据（确保是列表格式）
        col_data = df_normalized[col].tolist()
        
        # 应用手动归一化
        normalized_values = min_max_normalize(col_data)
        
        # 将归一化后的值放回DataFrame
        df_normalized[col] = normalized_values
    
    # 重命名归一化后的列，以便与原数据区分
    normalized_columns = {col: f'{col}_归一化' for col in numeric_cols}
    df_normalized = df_normalized.rename(columns=normalized_columns)
    
    # 将归一化后的数据与原数据进行横向合并
    df_combined = pd.merge(df, df_normalized[[key for key in normalized_columns.values()]], 
                          left_index=True, right_index=True)
    
    print('归一化后的数据前5行:')
    print(df_combined[[col for col in numeric_cols] + [normalized_columns[col] for col in numeric_cols]].head())
    
    # 5. 将预处理后的数据保存在本地
    output_file = '新浪财经历史分红数据_预处理.xlsx'
    df_combined.to_excel(output_file, index=False, engine='openpyxl')
    print(f'\n预处理后的数据已保存至{output_file}')
    
    # 保存为CSV格式备用
    csv_output_file = '新浪财经历史分红数据_预处理.csv'
    df_combined.to_csv(csv_output_file, index=False, encoding='utf-8-sig')
    print(f'预处理后的数据也已保存至{csv_output_file}')
    
    # 显示最终数据形状
    print(f'\n预处理后的数据形状: {df_combined.shape}')
    
    print('\n数据预处理完成！')
    
except Exception as e:
    print(f'处理数据时出错: {str(e)}')
    # 保存错误信息以便调试
    with open('data_processing_error.log', 'w', encoding='utf-8') as f:
        f.write(str(e))